package jp.co.cos.ittrick.channel.service;

import java.util.Date;

import jp.co.cos.ittrick.channel.common.exception.DatastorePutException;
import jp.co.cos.ittrick.channel.common.exception.DoubleInsertException;
import jp.co.cos.ittrick.channel.meta.ChapterModelMeta;
import jp.co.cos.ittrick.channel.model.ChapterModel;

import org.slim3.datastore.Datastore;
import org.slim3.memcache.Memcache;

import com.google.appengine.api.datastore.Key;
import com.google.appengine.api.datastore.Transaction;


public class ChapterService {

    /**
     * キーによるクラスの取得
     * @param pkKey
     * @return ChannelModel
     */
    public ChapterModel getChapterByKey(int chapterKey) {

        Key chapterPkKey = Datastore.createKey(ChapterModelMeta.get(), chapterKey);

        // Memcache に存在した場合はMemcache内のmodelを返す
        ChapterModel chapterModel = Memcache.get(chapterPkKey);
        if(chapterModel != null) return chapterModel;

        // DBから取得し、存在した場合はMemcacheに入れる
        chapterModel = Datastore.getOrNull(ChapterModel.class, chapterPkKey);
        if(chapterModel != null) Memcache.put(chapterPkKey, chapterModel);

        return chapterModel;
    }

    /**
     * Insert
     * @param pkKey
     * @param model
     * @return key
     * @throws DoubleInsertException
     * @throws DatastorePutException
     */
    public Key insert(ChapterModel model)
    throws DoubleInsertException, DatastorePutException {

        // キーの作成
        Key key = null;
        model.setLastmod(new Date());

        // insert
        Transaction tx = Datastore.beginTransaction();
        try {
            key = Datastore.put(tx, model);
            tx.commit();
        }
        catch (Exception e) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw new DatastorePutException();
        }

        return key;
    }


    /**
     * Update
     * @param model
     * @throws DatastorePutException
     */
    public void update(ChapterModel model) throws DatastorePutException {

        model.setLastmod(new Date());

        // Local Transaction の開始
        Transaction tx = Datastore.beginTransaction();

        try {
            // バージョンによる変更チェック
            Datastore.get(tx, ChapterModelMeta.get(), model.getKey(), model.getVersion());
            // 更新
            Datastore.put(tx, model);

            tx.commit();

            // Memcacheを削除する
            Memcache.delete(model.getKey());

        }catch (Exception e) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw new DatastorePutException();
        }
    }

    /**
     * 削除
     * @param serialPkKey
     * @param articleNum
     * @param articlePageNum
     * @throws Exception
     */
    public void delete(int pkKey) throws Exception {

        ChapterModel chapterModel = getChapterByKey(pkKey);
        Key pageKey = chapterModel.getKey();

        // Local Transaction の開始
        Transaction tx = Datastore.beginTransaction();

        try {
            Datastore.delete(tx, pageKey);

            tx.commit();

        }catch (Exception e) {
            if (tx.isActive()) {
                tx.rollback();
            }
            throw e;
        }
    }
}
